package cn.buddha.jec.util;

import java.util.HashMap;
import java.util.Map;

/**
 * @ClassName TongThreadLocalUtil
 * @Author 友野浩二
 * @Date 2020/4/3 16:06
 * @Description 线程工具类
 * @Version 1.0
 *
 * <pre>
 *     ThreadLocal和Synchonized都用于解决多线程并发访问。ThreadLocal与synchronized有本质的区别。
 *     1- Synchronized用于线程间的数据共享，而ThreadLocal则用于线程间的数据隔离。
 *     2- Synchronized是利用锁的机制，使变量或代码块在某一时该只能被一个线程访问。
 *        而ThreadLocal为每一个线程都提供了变量的副本，使得每个线程在某一时间访问到的并不是同一个对象，这样就隔离了多个线程对数据的数据共享。
 *        而Synchronized却正好相反，它用于在多个线程间通信时能够获得数据共享。
 *     ThreadLocal 适用于每个线程需要自己独立的实例且该实例需要在多个方法中被使用（相同线程数据共享），也就是变量在线程间隔离（不同的线程数据隔离）而在方法或类间共享的场景。
 *     相同线程数据共享不同的线程数据隔离。
 * </pre>
 */
public class TongThreadLocalUtil {

    private static ThreadLocal<Map<String, Object>> tongThreadLocal = ThreadLocal.withInitial(HashMap::new);

    private static final String TONG_CONTEXT_KEY = "TONG_CONTEXT";

    /**
     * @return
     * @Author 友野浩二
     * @Description // 设置彤彤的交易上下文容器
     * @Date 2020/4/4 21:47
     * @Param [tongContext]
     */
    public static <T> void setTongContext(T tongContext) {
        tongThreadLocal.get().put(TONG_CONTEXT_KEY, tongContext);
    }

    /**
     * @return T
     * @Author 友野浩二
     * @Description // 获取彤彤的交易上下文容器
     * @Date 2020/4/4 22:33
     * @Param []
     */
    public static <T> T getTongContext() {
        return (T) tongThreadLocal.get().get(TONG_CONTEXT_KEY);
    }

    /**
     * @return
     * @Author 友野浩二
     * @Description // 清空线程的所有东东
     * @Date 2020/4/4 22:36
     * @Param []
     */
    public static void removeTongThreadLocal() {
        tongThreadLocal.remove();
    }

    /**
     * @return void
     * @Author 友野浩二
     * @Description // 在当前线程设置值
     * @Date 2020/4/4 22:49
     * @Param [key, value]
     */
    public static void put(String key, Object value) {
        tongThreadLocal.get().put(key, value);
    }

    /**
     * @return java.lang.Object
     * @Author 友野浩二
     * @Description // 在当前线程根据key获取value
     * @Date 2020/4/4 22:53
     * @Param [key]
     */
    public static Object get(String key) {
        return tongThreadLocal.get().get(key);
    }

    /**
     * @return java.util.Map<java.lang.String, java.lang.Object>
     * @Author 友野浩二
     * @Description // 在当前线程获取所有键值
     * @Date 2020/4/4 22:54
     * @Param []
     */
    public static Map<String, Object> getTongThreadAllInfo() {
        return tongThreadLocal.get();
    }
}
